//=============================================================================
//
//   File : qtg_appinstaller.cpp
//   Creation date : Sab 19 mar 2011 09:31:42 CET by Antonino G.Imbesi
//
//   This file is part of the QtGLauncher distribution
//   Copyright (C) 2011 Antonino G. Imbesi <grifisx at barmes dot org>
//
//   This program is FREE software. You can redistribute it and/or
//   modify it under the terms of the GNU General Public License
//   as published by the Free Software Foundation; either version 2
//   of the License, or (at your opinion) any later version.
//
//   This program is distributed in the HOPE that it will be USEFUL,
//   but WITHOUT ANY WARRANTY; without even the implied warranty of
//   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
//   See the GNU General Public License for more details.
//
//   You should have received a copy of the GNU General Public License
//   along with this program. If not, write to the Free Software Foundation,
//   Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================

#include <QVBoxLayout>
#include <QWidget>
#include <QFileDialog>
#include <QLabel>
#include <QGroupBox>
#include <QPushButton>
#include <QFileDialog>
#include <QLineEdit>
#include <QPushButton>
#include <QDir>
#include <QFileInfo>
#include <QFileInfoList>
#include <QFileInfoListIterator>
#include <QMessageBox>
#include <QTextEdit>
#include <QDebug>
#include <QScrollBar>
#include <QSettings>
#include <QComboBox>
#include <QXmlStreamReader>
#include <QtXml/QDomDocument>

#include "qtg_qpushbutton.h"
#include "qtg_appinstaller.h"

qtg_appinstaller::qtg_appinstaller(QWidget *parent, QSettings *settings ) :
        QWizard(parent)
{
    m_appConf = settings;
    setMinimumSize(500,450);
    setObjectName("installerWizard");
    setOption(QWizard::IndependentPages,true);
    setWindowTitle(tr("Installazione Wizard - QtGLauncher"));
    // Welcome page
    QWizardPage * pPage = new QWizardPage(this);
    QVBoxLayout * pLayout = new QVBoxLayout;

    pPage->setLayout(pLayout);
    pPage->setTitle(tr("Benvenuto"));

    QLabel * pLabel = new QLabel(pPage);
    pLabel->setWordWrap(true);


    QString szText;
    szText = tr("Questa procedura ti guidera all'aggiunta di una nuova applicazione portatile al menu' principale.<br>\
                Ti verra' chiesto di indicare la directory dell'applicazione che sta installando.<br>\
                Il percorso del binario e dell'icona, assicurati di conoscerle.\
                <br><br>\
                Premi \"Next\" per iniziare.\
                ");
    pLabel->setText(szText);
    pLayout->addWidget(pLabel);


    addPage(pPage);
    // Folder selection
    qtg_pathselectionwizard *pFolderPage = new qtg_pathselectionwizard(this);
    qtg_binselectionwizard *pBinIconPage = new qtg_binselectionwizard(this);
    qtg_categoryselectionwizard *pCategoryPage = new qtg_categoryselectionwizard(this);
    qtg_finalpagewizard *pFinalPage = new qtg_finalpagewizard(this);

    addPage(pFolderPage);
    addPage(pBinIconPage);
    addPage(pCategoryPage);
    addPage(pFinalPage);
}

qtg_appinstaller::~qtg_appinstaller()
{
}






/************************************
/-Class--------Folder selector page:-
************************************/


qtg_pathselectionwizard::qtg_pathselectionwizard(qtg_appinstaller *parent)
    : QWizardPage(parent)
{

    QVBoxLayout * pLayout = new QVBoxLayout;
    QHBoxLayout * pSelectionLayout = new QHBoxLayout;
    setLayout(pLayout);
    setTitle(tr("Selezione cartella"));

    QLabel * pLabel = new QLabel;
    pLabel->setWordWrap(true);

    m_pTextCopyEdit = new QTextEdit;
    m_pTextCopyEdit->setReadOnly(1);
    m_psbTextCopyEdit=m_pTextCopyEdit->verticalScrollBar();

    QString szText;
    szText = tr("Adesso dovrai selezionare la cartella del programma che verra\' installato.<br>\
                Successivamente premi sul pulsante Avvia.<br>\
                La cartella verra\' copiata nella directory giusta dentro la cartella Apps.<br>\
                Assicurati che i nomi delle cartelle non contengano spazi, su alcuni sistemi operativi la loro presenza\
                potrebbe creare problemi.\
                <br><br>\
                Premi \"Next\" per continure.\
                ");
    pLabel->setText(szText);
    m_pPathLine = new QLineEdit;
    registerField("programmPath*",m_pPathLine);
    m_pPathLine->setReadOnly(1);
    qtg_qpushbutton *pPathBtn = new qtg_qpushbutton;
    pPathBtn->setText("Sfoglia");
    pPathBtn->setIcon(QIcon("./themes/"+parent->m_appConf->value("Config/themePath").toString()+"/sfoglia.png"));

    connect(pPathBtn, SIGNAL(clicked()),
            this, SLOT(registerPath()));

    m_pOkBtn = new qtg_qpushbutton;
    m_pOkBtn->setText("Avvia");
    m_pOkBtn->setDisabled(1);

    connect(m_pOkBtn, SIGNAL(clicked()),
            this, SLOT(startCopy()));

    pSelectionLayout->addWidget(m_pPathLine);
    pSelectionLayout->addWidget(pPathBtn);
    pSelectionLayout->addWidget(m_pOkBtn);

    pLayout->addWidget(pLabel);
    pLayout->addLayout(pSelectionLayout);
    pLayout->addWidget(m_pTextCopyEdit);
}

qtg_pathselectionwizard::~qtg_pathselectionwizard()
{
}

void qtg_pathselectionwizard::registerPath()
{

    m_szSourceDir = QFileDialog::getExistingDirectory(0, tr("Open Directory"),\
                                                      "./",\
                                                      QFileDialog::ShowDirsOnly\
                                                      | QFileDialog::DontResolveSymlinks);
    m_pPathLine->setText(m_szSourceDir);
    m_pPathLine->setToolTip(m_szSourceDir);
    m_szDestDir = QDir::currentPath()+"/Apps/"+m_szSourceDir.section('/',-1);
    m_pOkBtn->setDisabled(0);
}

void qtg_pathselectionwizard::cpDir(QString &sourceFolder,QString &destFolder)
{
    QDir sourceDir(sourceFolder);
    if(!sourceDir.exists())
    {
        QMessageBox::information(this,"Installer...",tr("Directory sorgente inesistente."));
        return;
    }
    QDir destDir(destFolder);
    if(!destDir.exists())
    {
        if(!destDir.mkdir(destFolder)){
            QMessageBox::information(this,"Installer...",tr("Errore, impossibile creare la directory."));
            m_pTextCopyEdit->insertHtml("<b>Errore!</b><br>");
        }
        else
            m_pTextCopyEdit->insertHtml("<b>Creo la cartella :</b>"+destFolder+"<FONT COLOR=\"#00FF00\"> Ok </FONT><br>");
        m_psbTextCopyEdit->setValue(m_psbTextCopyEdit->maximum());
    }
    QStringList files = sourceDir.entryList(QDir::Files);
    for(int i = 0; i< files.count(); i++)
    {
        QString srcName = sourceFolder + "/" + files[i];
        QString destName = destFolder + "/" + files[i];

        if(!QFile::copy(srcName, destName)){
            QMessageBox::information(this,"Installer...",tr("Errore, impossibile copiare il file."));
            m_pTextCopyEdit->insertHtml("<b>Errore!</b>");
        }
        else
            m_pTextCopyEdit->insertHtml("<b>Copio il file: </b>"+srcName+"<FONT COLOR=\"#00FF00\"> Ok </FONT><br>");
        m_psbTextCopyEdit->setValue(m_psbTextCopyEdit->maximum());
    }
    files.clear();
    files = sourceDir.entryList(QDir::AllDirs | QDir::NoDotAndDotDot);
    for(int i = 0; i< files.count(); i++)
    {
        QString srcName = sourceFolder + "/" + files[i];
        QString destName = destFolder + "/" + files[i];
        cpDir(srcName, destName);
    }
    m_psbTextCopyEdit->setValue(m_psbTextCopyEdit->maximum());
}
void qtg_pathselectionwizard::startCopy()
{
    m_pTextCopyEdit->insertHtml("<b>Attendere...!</b><br>");
    m_pOkBtn->setDisabled(1);
    cpDir( m_szSourceDir, m_szDestDir);
    m_pTextCopyEdit->insertHtml("<br><b>Terminato! </b><br>");
}





/************************************
/-Class--Bin and Icon selector page:-
************************************/


qtg_binselectionwizard::qtg_binselectionwizard(qtg_appinstaller *parent)
    : QWizardPage(parent)
{
    QVBoxLayout * pMainLayout = new QVBoxLayout;
    QHBoxLayout * pLayout = new QHBoxLayout;

    QVBoxLayout * pLabelLayout = new QVBoxLayout;
    QVBoxLayout * pLineBtnLayout = new QVBoxLayout;

    QHBoxLayout * pBinSelectionLayout = new QHBoxLayout;
    QHBoxLayout * pIconSelectionLayout = new QHBoxLayout;

    setLayout(pMainLayout);
    setTitle(tr("Selezione cartella"));

    QLabel * pLabel = new QLabel;
    pLabel->setWordWrap(true);

    QString szText;
    szText = tr("Adesso dovrai selezionare il file binario del programma e il file della sua icona.<br>\
                Il binario dovra\' essere quello della cartella copiata in Apps e non della sua cartella originale.<br>\
                Per l\'icona si consiglia di prediligere i file png.\
                <br><br>\
                Premi \"Next\" per continure.\
                ");
    pLabel->setText(szText);
    m_pBinPathLine = new QLineEdit;
    QLabel *pBinLabel = new QLabel;
    pBinLabel->setText("Seleziona il binario: ");

    registerField("binPath*",m_pBinPathLine);
    m_pBinPathLine->setReadOnly(1);
    qtg_qpushbutton *pBinPathBtn = new qtg_qpushbutton;
    pBinPathBtn->setText("Sfoglia");
    pBinPathBtn->setIcon(QIcon("./themes/"+parent->m_appConf->value("Config/themePath").toString()+"/sfoglia.png"));

    connect(pBinPathBtn, SIGNAL(clicked()),
            this, SLOT(registerBinPath()));



    m_pParamsLine = new QLineEdit;
    QLabel *pParamsLabel = new QLabel;
    pParamsLabel->setText("Parametri di avvio: ");
    registerField("paramsBin",m_pParamsLine);


    m_pIconPathLine = new QLineEdit;
    QLabel *pIconLabel = new QLabel;
    pIconLabel->setText("Seleziona l'cona: ");
    registerField("iconPath*",m_pIconPathLine);
    m_pIconPathLine->setReadOnly(1);
    qtg_qpushbutton *pIconPathBtn = new qtg_qpushbutton;
    pIconPathBtn->setText("Sfoglia");
    pIconPathBtn->setIcon(QIcon("./themes/"+parent->m_appConf->value("Config/themePath").toString()+"/sfoglia.png"));

    connect(pIconPathBtn, SIGNAL(clicked()),
            this, SLOT(registerIconPath()));

    pLabelLayout->addWidget(pBinLabel);
    pLabelLayout->addWidget(pParamsLabel);
    pLabelLayout->addWidget(pIconLabel);

    pBinSelectionLayout->addWidget(m_pBinPathLine);
    pBinSelectionLayout->addWidget(pBinPathBtn);

    pIconSelectionLayout->addWidget(m_pIconPathLine);
    pIconSelectionLayout->addWidget(pIconPathBtn);

    pLineBtnLayout->addLayout(pBinSelectionLayout);
    pLineBtnLayout->addWidget(m_pParamsLine);
    pLineBtnLayout->addLayout(pIconSelectionLayout);


    pLayout->addLayout(pLabelLayout);
    pLayout->addLayout( pLineBtnLayout);

    pMainLayout->addWidget(pLabel);
    pMainLayout->addLayout(pLayout);
}

qtg_binselectionwizard::~qtg_binselectionwizard()
{
}

void qtg_binselectionwizard::registerBinPath()
{
    QString destName =QDir::currentPath()+"/pics/software/";
    QString fileName = QFileDialog::getOpenFileName(this,
                                                    tr("Seleziona il binario"), "./", tr("All Files (*)"));

    m_pBinPathLine->setText("./Apps"+fileName.section("Apps",-1));
    m_pBinPathLine->setToolTip(m_pBinPathLine->text());
}

void qtg_binselectionwizard::registerIconPath()
{
    QString destName =QDir::currentPath()+"/pics/software/";
    QString fileName = QFileDialog::getOpenFileName(this,
                                                    tr("Seleziona l'icona"), "./", tr("Image Files (*.png *.ico)"));

    if(!QFile::copy(fileName, destName+fileName.section('/',-1)))
    {
        QMessageBox::information(this,"Installer...",tr("Errore, impossibile copiare il file."));
    }
    else
    {
        m_pIconPathLine->setText("./pics/software/"+fileName.section('/',-1));
        m_pIconPathLine->setToolTip(m_pIconPathLine->text());
    }
}





/************************************
/-Class--Category selector page:-
************************************/

qtg_categoryselectionwizard::qtg_categoryselectionwizard(qtg_appinstaller *parent)
    : QWizardPage(parent)
{
    m_pXmlStream = new QXmlStreamReader;

    QVBoxLayout * pMainLayout = new QVBoxLayout;
    QHBoxLayout * pLayout = new QHBoxLayout;

    setLayout(pMainLayout);
    setTitle(tr("Selezione la categoria"));

    QLabel * pLabel = new QLabel;
    pLabel->setWordWrap(true);

    QString szText;
    szText = tr("Adesso dovrai selezionare la categoria in cui inserire la tua applicazione.\
                <br><br>\
                Premi \"Next\" per continure.\
                ");
    pLabel->setText(szText);

    m_pCategoryLine = new QLineEdit;

    m_pComboCategory = new QComboBox;
#ifdef Q_WS_WIN32
    QString fileName ="./config/qtglauncher_win.xml";
#endif
#ifdef Q_WS_X11
    QString fileName ="./config/qtglauncher.xml";
#endif
#ifdef Q_WS_MACX
    QString fileName ="./config/qtglauncher_macos.xml";
#endif
    QFile file(fileName);

    if (!file.open(QFile::ReadOnly | QFile::Text)) {
        QMessageBox::warning(this, tr("QtGLauncer"),
                             tr("Cannot read file %1:\n%2.")
                             .arg(fileName)
                             .arg(file.errorString()));
        return;
    }

    m_pXmlStream->setDevice(&file);
    int idx =0;
    while (xmlreadNextStartElement())
    {
        if (m_pXmlStream->name() == "Category")
        {
            m_pComboCategory->insertItem(idx,QIcon(m_pXmlStream->attributes().value("pathicon").toString()), m_pXmlStream->attributes().value("name").toString());
            idx++;
            xmlskipCurrentElement();
        }

    }

    registerField("categoryName*",m_pCategoryLine);
    m_pCategoryLine->setReadOnly(1);

    connect(m_pComboCategory, SIGNAL(currentIndexChanged( const QString)),
            this, SLOT(registerCategory(const QString)));


    pLayout->addWidget(m_pCategoryLine);
    pLayout->addWidget(m_pComboCategory);

    pMainLayout->addWidget(pLabel);
    pMainLayout->addLayout(pLayout);
}

qtg_categoryselectionwizard::~qtg_categoryselectionwizard()
{
}

void qtg_categoryselectionwizard::registerCategory(const QString string)
{
    m_pCategoryLine->setText(string);
}

bool qtg_categoryselectionwizard::xmlreadNextStartElement()
{
    // This functions are to emulate new xml functions in old QT
    if(QT_VERSION > 4.7){
        //    qDebug () << "Qt > 4.7";
        return m_pXmlStream->readNextStartElement();}
    else{
        //   qDebug () << "Qt < 4.7";
        while (m_pXmlStream->readNext() != QXmlStreamReader::Invalid) {
            if (m_pXmlStream->isEndElement())
                return false;
            else if (m_pXmlStream->isStartElement())
                return true;
        }
        return false;
    }

}

void qtg_categoryselectionwizard::xmlskipCurrentElement()
{
    // This functions are to emulate new xml functions in old QT
    if(QT_VERSION > 4.7){
        m_pXmlStream->skipCurrentElement();
    }
    else
    {
        while (xmlreadNextStartElement())
            xmlskipCurrentElement();
    }
}





/************************************
/-Class--Final Page xml writer:-
************************************/

qtg_finalpagewizard::qtg_finalpagewizard(qtg_appinstaller *parent)
    : QWizardPage(parent)
{

    QVBoxLayout * pMainLayout = new QVBoxLayout;
    setLayout(pMainLayout);
    setTitle(tr("Completamento installazione."));

    QLabel * pLabel = new QLabel;
    pLabel->setWordWrap(true);

    QString szText;
    szText = tr("L'installazione è terminata.\
                <br><br>\
                Premi \"Next\" per continure.\
                ");
    pLabel->setText(szText);

    qtg_qpushbutton *pCatBtn = new qtg_qpushbutton;
    pCatBtn->setText("Salva");
    pCatBtn->setIcon(QIcon("./themes/"+parent->m_appConf->value("Config/themePath").toString()+"/sfoglia.png"));
    connect(pCatBtn, SIGNAL(clicked()),
            this, SLOT(registerCat()));



    pMainLayout->addWidget(pLabel);
    pMainLayout->addWidget(pCatBtn);
}

qtg_finalpagewizard::~qtg_finalpagewizard()
{
}

void qtg_finalpagewizard::registerCat()
{
    QDomNode newNode = new QDomNode;
    newNode.setNodeValue(
#ifdef Q_WS_WIN32
    QString fileName ="./config/qtglauncher_win.xml";
#endif
#ifdef Q_WS_X11
    QString fileName ="./config/qtglauncher.xml";
#endif
#ifdef Q_WS_MACX
    QString fileName ="./config/qtglauncher_macos.xml";
#endif
    QDomDocument *domDoc = new QDomDocument;
    QFile file(fileName);

    domDoc->setContent(&file);
    QDomNodeList list = domDoc->elementsByTagName("Category");
    int idx = list.count();
    while(idx>=0)
    {
        QDomElement nodeElement = list.at(idx).toElement();
        if(field("categoryName").toString()==nodeElement.attribute("name"))
        {
            nodeElement.appendChild()
            qDebug() << "I find the Node!" << field("categoryName").toString() << nodeElement.attribute("name");
        }
        idx--;
    }


}
